import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  DoCheck,
  ElementRef,
  Input,
  OnInit,
  ViewChild
} from '@angular/core';
import { TranslateService } from "@ngx-translate/core";
import { forkJoin } from "rxjs";

@Component({
  selector: 'histogram-chart',
  templateUrl: './histogram-chart.component.html',
  styleUrls: ['./histogram-chart.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HistogramChartComponent implements OnInit, AfterViewInit, DoCheck {
  @Input()
  metadata: Array<{
    text: string,
    value: number,
    color: string
  }> = [];
  translatedTextArr: Array<string> = [];
  @Input()
  isWhiteBackground: boolean = false;
  max: number;
  scale: number;
  hasViewInit: boolean = false;
  @ViewChild('barChart') barChart: ElementRef;
  public context: CanvasRenderingContext2D;
  constructor(private translate: TranslateService) { }

  ngOnInit() {
    this.translateText();
  }
  ngAfterViewInit(): void {
    this.hasViewInit = true;
    this.initChart();
  }
  ngDoCheck() {
    if (this.hasViewInit) {
      this.initChart();
    }
  }
  translateText() {
    if (this.metadata && this.metadata.length > 0) {
      let textArr = [];
      this.metadata.forEach(item => {
        textArr.push(this.translate.get(item.text));
      });
      forkJoin(textArr).subscribe(
          (res: string[]) => {
            this.translatedTextArr = res;
            if (this.hasViewInit) {
              this.initChart();
            }
          }
      );
    }
  }
  initChart() {
    if (this.barChart && this.metadata && this.metadata.length > 0) {
      this.barChart.nativeElement.width = "240";
      this.barChart.nativeElement.height = 25 + 20 * this.metadata.length + "";
      this.context = this.barChart.nativeElement.getContext('2d');
      this.getMax();
      if (this.isWhiteBackground) {
        this.context.fillStyle = "#000";
      } else {
        this.context.fillStyle = "#fff";
      }
      this.drawLine(50, 0, 50, 5 + this.metadata.length * 20);
      this.drawLine(50, 5 + this.metadata.length * 20, 250, 5 + this.metadata.length * 20);
      this.drawLine(90, 5 + this.metadata.length * 20, 90, 2 + this.metadata.length * 20);
      this.drawLine(130, 5 + this.metadata.length * 20, 130, 2 + this.metadata.length * 20);
      this.drawLine(170, 5 + this.metadata.length * 20, 170, 2 + this.metadata.length * 20);
      this.drawLine(210, 5 + this.metadata.length * 20, 210, 2 + this.metadata.length * 20);
      this.context.font = "12px";
      this.context.textAlign = "center";
      this.context.fillText(this.scale.toString(), 90, this.metadata.length * 20 + 18, 50);
      this.context.fillText((2 * this.scale).toString(), 130, this.metadata.length * 20 + 18, 50);
      this.context.fillText((3 * this.scale).toString(), 170, this.metadata.length * 20 + 18, 50);
      this.context.fillText((4 * this.scale).toString(), 210, this.metadata.length * 20 + 18, 50);
      this.metadata.forEach((item, index) => {
        this.drawBar(index, item.color, item.value);
      });
    }
  }
  drawBar(index: number, color: string, value: number) {
    this.context.textBaseline = "middle";
    this.context.textAlign = "left";
    this.context.fillStyle = color;
    this.context.fillRect(50, 5 + index * 20, value / this.scale * 40, 15);
    this.context.fillText(value.toString(), (value / this.scale * 40) + 53, 12 + index * 20, 37);
    this.context.textAlign = "right";
    let text = "";
    if (this.translatedTextArr && this.translatedTextArr.length > 0) {
      text = this.translatedTextArr[index];
    } else {
      text = this.metadata[index].text;
    }
    this.context.fillText(text, 47, 12 + index * 20, 47);
  }
  drawLine(x, y, X, Y) {
    this.context.beginPath();
    this.context.moveTo(x, y);
    this.context.lineTo(X, Y);
    if (this.isWhiteBackground) {
      this.context.strokeStyle = "#000";
    } else {
      this.context.strokeStyle = "#fff";
    }
    this.context.stroke();
    this.context.closePath();
  }
  getMax() {
    let count = 1;
    if (this.metadata && this.metadata.length > 0) {
      this.metadata.forEach(item => {
        if (item.value > count) {
          count = item.value;
        }
      });
    }
    this.max = count;
    this.scale = Math.ceil(count / 40) * 10;
  }
}
